Skip to content

Delay external dependency imports to class initialization - #1257

Merged
bact merged 10 commits into
devfrom
copilot/refactor-delayed-imports
Feb 3, 2026
Merged

Delay external dependency imports to class initialization#1257
bact merged 10 commits into
devfrom
copilot/refactor-delayed-imports

Conversation

Copilot AI commented Feb 2, 2026

Copy link
Copy Markdown
Contributor

What do these changes do

Moves module-level imports of heavy external dependencies (transformers, torch, gensim, numpy, spacy) to class initialization methods, enabling module imports without requiring optional dependencies.

What was wrong

Module-level imports forced dependency resolution at import time, blocking:

  • Documentation tools from importing modules without full dependency installation
  • Module-level helper functions from working independently
  • Clear error context (failures at import vs. instantiation)

Example failure case:

from pythainlp.word_vector import core  # Fails if gensim not installed
# Even if you only wanted to use a helper function, not WordVector class

How this fixes it

Defers dependency imports to where they're actually needed:

Pattern 1: Import in __init__

class KeyBERT:
    def __init__(self, model_name: str):
        from transformers import pipeline  # Loaded only when class instantiated
        self.ft_pipeline = pipeline(...)

Pattern 2: Import in method

def sentence_vectorizer(self, text: str) -> ndarray:
    from numpy import zeros  # Loaded only when method called
    vec = zeros((1, self.WV_DIM))

Pattern 3: Lazy module-level via getter

_tokenizer = None

def _get_tokenizer():
    global _tokenizer
    if _tokenizer is None:
        from transformers import CamembertTokenizer
        _tokenizer = CamembertTokenizer.from_pretrained(...)
    return _tokenizer

Used TYPE_CHECKING guards to preserve type hints without runtime imports. Updated type hints to use native Python 3.9+ lowercase types (list, dict) with Union from typing module for compatibility with Python 3.9 strict mode and type inspection tools.

Modified modules (9):

  • word_vector/core.py - gensim, numpy
  • summarize/keybert.py - numpy, transformers
  • summarize/mt5.py - transformers
  • wangchanberta/core.py - transformers (tokenizer)
  • coref/_fastcoref.py - spacy
  • coref/han_coref.py - spacy
  • parse/transformers_ud.py - transformers, numpy, torch, ufal (uses Union[list[list[str]], str] syntax)
  • augment/lm/wangchanberta.py - transformers
  • augment/lm/fasttext.py - gensim

Your checklist for this pull request

  • Passed code styles and structures
  • Passed code linting checks and unit test
Original prompt

Find the module level imports of external dependencies that could be import at the initialization step of the class inside that module instead.

Basically try to delaying the import until the point of creating an object, instead of immediately import external dependencies at the point of the module import.

this will

  • Allows helper functions in that module (if any) to work without external dependencies
  • Module can be imported for documentation generation
  • Clear error only when class is instantiated

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 3 commits February 2, 2026 18:19
- word_vector/core.py: Move gensim and numpy imports into methods
- summarize/keybert.py: Move numpy and transformers imports into methods
- summarize/mt5.py: Move transformers imports into __init__
- wangchanberta/core.py: Lazy load tokenizer via helper function
- coref/_fastcoref.py: Move spacy import to inside __init__, avoid default mutable arg

Co-authored-by: bact <128572+bact@users.noreply.github.com>
- augment/lm/wangchanberta.py: Move transformers imports to __init__
- augment/lm/fasttext.py: Move gensim imports to __init__
- coref/han_coref.py: Remove spacy import from default parameter
- parse/transformers_ud.py: Move heavy ML imports to __init__ and __call__

Co-authored-by: bact <128572+bact@users.noreply.github.com>
- Add TYPE_CHECKING imports for type hints without runtime imports
- Restore type hints using proper forward references
- Address code review feedback about preserving type information

Co-authored-by: bact <128572+bact@users.noreply.github.com>
Copilot AI changed the title [WIP] Refactor module to delay external dependencies imports Delay external dependency imports to class initialization Feb 2, 2026
Copilot AI requested a review from bact February 2, 2026 18:39
@bact
bact requested a review from Copilot February 2, 2026 19:44
@bact
bact marked this pull request as ready for review February 2, 2026 20:00
@bact bact added the refactoring a technical improvement which does not add any new features or change existing features. label Feb 2, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@bact
bact requested a review from Copilot February 2, 2026 20:12

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Comment thread tests/data/text-misspelled-r0.05-seed1.txt Outdated
Comment thread pythainlp/summarize/keybert.py Outdated
bact and others added 2 commits February 2, 2026 20:31
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Comment thread pythainlp/parse/transformers_ud.py Outdated
Copilot AI requested a review from bact February 2, 2026 21:15
Copilot stopped work on behalf of bact due to an error February 2, 2026 21:15
Copilot stopped work on behalf of bact due to an error February 2, 2026 21:27
@bact

bact commented Feb 3, 2026

Copy link
Copy Markdown
Member

@copilot review again

- Restore tests/data/text-misspelled-r0.05-seed1.txt (was accidentally deleted)
- Use Python 3.9+ native union syntax (list[list[str]] | str) instead of Union
- Remove unused typing imports (List, Union)

Co-authored-by: bact <128572+bact@users.noreply.github.com>

Copilot AI commented Feb 3, 2026

Copy link
Copy Markdown
Contributor Author

@copilot review again

All review comments have been addressed in commit 6a2a398:

  • Restored tests/data/text-misspelled-r0.05-seed1.txt that was accidentally deleted
  • Updated pythainlp/parse/transformers_ud.py to use Python 3.9+ native union syntax (list[list[str]] | str)
  • Removed unused typing.Union and typing.List imports

All 111 core tests pass and Ruff linting checks succeed.

@bact

bact commented Feb 3, 2026

Copy link
Copy Markdown
Member

@copilot
Use native type in type hint.
But do not use A | B style Union.
We want to keep compatibility with Python 3.9 strict and allow type inspection tools to work correctly.

- Change from PEP 604 union syntax (list[list[str]] | str) to Union[list[list[str]], str]
- Maintain native lowercase list types for Python 3.9+
- Ensure compatibility with type inspection tools in Python 3.9 strict mode

Co-authored-by: bact <128572+bact@users.noreply.github.com>

Copilot AI commented Feb 3, 2026

Copy link
Copy Markdown
Contributor Author

@copilot
Use native type in type hint.
But do not use A | B style Union....

Updated in commit 0ec00ae to use Union[list[list[str]], str] instead of PEP 604 union syntax (|). This maintains Python 3.9 strict compatibility while using native lowercase list types. All 111 core tests pass and Ruff linting succeeds.

@sonarqubecloud

sonarqubecloud Bot commented Feb 3, 2026

Copy link
Copy Markdown

@bact bact added this to the 5.3 milestone Feb 3, 2026
@bact
bact merged commit 8c0f684 into dev Feb 3, 2026
23 of 33 checks passed
@bact
bact deleted the copilot/refactor-delayed-imports branch February 3, 2026 06:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

refactoring a technical improvement which does not add any new features or change existing features.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants